home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / share / dos / graficos / plydat14.arj / GEARS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-29  |  7.7 KB  |  231 lines

  1. /*
  2.  * gears.c - Create a set of gears.  Each gear face has 144 vertices, and
  3.  *   contains concavities.  Note that the first 3 vertices of all polygons
  4.  *   define the two edges of a convex section of the polygon.  Background
  5.  *   square floor is reflective.  Some gears are clipped.
  6.  *   Five light sources.
  7.  *
  8.  * Version:  2.2 (11/17/87)
  9.  * Author:  Eric Haines, 3D/Eye, Inc.
  10.  *
  11.  * SIZE_FACTOR determines the number of polygons output.
  12.  *     Total gears = SF**3:  concave polygons = 2 * SF**3
  13.  *     rectangles = 4*TEETH * SF**3
  14.  *
  15.  * SIZE_FACTOR   # gears # gear faces    # rectangles
  16.  *       1          1          2           144
  17.  *       2          8         16          1152
  18.  *       3         27         54          3888
  19.  *       4         64        128          9216
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <math.h>
  24. #ifdef MAC
  25. #include <console.h>
  26. #endif
  27. #include "def.h"
  28. #include "lib.h"
  29.  
  30. #define SIZE_FACTOR 2
  31.  
  32. /* define number of teeth on a gear - must be a multiple of 4 */
  33. #define TEETH 32
  34. /* define ratio of radius taken up by teeth and the gear thickness */
  35. #define EDGE_RATIO   0.1
  36. #define DEPTH_RATIO  0.1
  37.  
  38. /* Create gear tooth */
  39. static void
  40. create_tooth(double gear_angle, double tooth_angle,
  41.         COORD4 *center, COORD4 *outer_pt,
  42.         COORD4 *inner_pt, COORD4 *edge_pts)
  43. {
  44.     MATRIX   mx ;
  45.  
  46.  
  47.     lib_create_rotate_matrix( mx
  48.              , Z_AXIS
  49.              , gear_angle - 0.19 * tooth_angle ) ;
  50.     lib_transform_coord( &edge_pts[0], outer_pt, mx ) ;
  51.     ADD2_COORD( edge_pts[0], *center ) ;
  52.     lib_create_rotate_matrix( mx
  53.              , Z_AXIS
  54.              , gear_angle + 0.19 * tooth_angle ) ;
  55.     lib_transform_coord( &edge_pts[1], outer_pt, mx ) ;
  56.     ADD2_COORD( edge_pts[1], *center ) ;
  57.     lib_create_rotate_matrix( mx
  58.              , Z_AXIS
  59.              , gear_angle + 0.3 * tooth_angle ) ;
  60.     lib_transform_coord( &edge_pts[2], inner_pt, mx ) ;
  61.     ADD2_COORD( edge_pts[2], *center ) ;
  62.     lib_create_rotate_matrix( mx
  63.              , Z_AXIS
  64.              , gear_angle + 0.7 * tooth_angle ) ;
  65.     lib_transform_coord( &edge_pts[3], inner_pt, mx ) ;
  66.     ADD2_COORD( edge_pts[3], *center ) ;
  67. }
  68.  
  69.  
  70. /* Create gear */
  71. static void
  72. create_gear(COORD4 *center, double offset_angle, double outer_radius,
  73.        double inner_radius, double thickness,
  74.        char *txname)
  75. {
  76.     COORD4   side_pts[4], gear_pts[4*TEETH], outer_pt, inner_pt ;
  77.     long   next_side, num_side, num_teeth ;
  78.     double   gear_angle, tooth_angle ;
  79.  
  80.  
  81.     outer_pt.x = outer_radius ;
  82.     outer_pt.y = 0.0 ;
  83.     outer_pt.z = 0.0 ;
  84.     outer_pt.w = 1.0 ;
  85.     inner_pt.x = inner_radius ;
  86.     inner_pt.y = 0.0 ;
  87.     inner_pt.z = 0.0 ;
  88.     inner_pt.w = 1.0 ;
  89.  
  90.     tooth_angle = 2.0 * PI / (double)TEETH ;
  91.  
  92.     /* output gear top */
  93.     for ( num_teeth = 0 ; num_teeth < TEETH ; ++num_teeth ) {
  94.    gear_angle = offset_angle +
  95.       2.0 * PI * (double)num_teeth / (double)TEETH ;
  96.    create_tooth( gear_angle
  97.           , tooth_angle
  98.           , center
  99.           , &outer_pt
  100.           , &inner_pt
  101.           , &gear_pts[num_teeth*4]
  102.           ) ;
  103.     }
  104.     lib_output_polygon(4*TEETH, gear_pts, txname);
  105.  
  106.     /* output teeth */
  107.     for ( num_side = 0 ; num_side < 4 * TEETH ; ++num_side ) {
  108.    next_side = ( num_side + 1 ) % ( 4 * TEETH ) ;
  109.    COPY_COORD( side_pts[0], gear_pts[num_side] ) ;
  110.    COPY_COORD( side_pts[1], gear_pts[num_side] ) ;
  111.    side_pts[1].z -= thickness ;
  112.    COPY_COORD( side_pts[2], gear_pts[next_side] ) ;
  113.    side_pts[2].z -= thickness ;
  114.    COPY_COORD( side_pts[3], gear_pts[next_side] ) ;
  115.    lib_output_polygon(4, side_pts, txname);
  116.     }
  117.  
  118.     /* output gear bottom */
  119.     outer_pt.z = inner_pt.z = -thickness ;
  120.     for ( num_teeth = 0 ; num_teeth < TEETH ; ++num_teeth ) {
  121.    gear_angle = offset_angle -
  122.       2.0 * PI * (double)num_teeth / (double)TEETH ;
  123.    create_tooth( gear_angle
  124.           , -tooth_angle
  125.           , center
  126.           , &outer_pt
  127.           , &inner_pt
  128.           , &gear_pts[num_teeth*4]
  129.           ) ;
  130.     }
  131.     lib_output_polygon(4*TEETH, gear_pts, txname);
  132. }
  133.  
  134. void
  135. main(int argc, char *argv[])
  136. {
  137.    COORD4  back_color, gear_color ;
  138.    COORD4  center_pt, floor[4], light, offset, zero_pt ;
  139.    COORD4  from, at, up, dir;
  140.    double  angle, color_scale, outer_radius, thickness ;
  141.    long    ix, iy, iz ;
  142.    char    *txname;
  143.  
  144. #ifdef MAC
  145.    argc = ccommand(&argv);
  146. #endif
  147.  
  148.    /* output viewpoint */
  149.    SET_COORD( from, -1.1, -2.1, 2.6 ) ;
  150.    SET_COORD( at, 0.0, 0.0, 0.0 ) ;
  151.    SET_COORD( up, 0.0, 0.0, 1.0 ) ;
  152.    lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
  153.  
  154.    /* output background color - UNC sky blue */
  155.    SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
  156.    lib_output_background_color( &back_color ) ;
  157.  
  158.    /* output light sources */
  159.    SET_COORD( light, 2.0, 4.0, 4.0 ) ;
  160.    lib_output_light( &light ) ;
  161.    SET_COORD( light, -2.0, 4.0, 3.0 ) ;
  162.    lib_output_light( &light ) ;
  163.    SET_COORD( light, 2.0, -2.5, 2.5 ) ;
  164.    lib_output_light( &light ) ;
  165.    SET_COORD( light, -1.0, -4.0, 2.0 ) ;
  166.    lib_output_light( &light ) ;
  167.    /* just behind the eye */
  168.    SET_COORD( light, -1.111, -2.121, 2.626 ) ;
  169.    lib_output_light( &light ) ;
  170.  
  171.     /* Output bounding slabs oriented along the coordinate axes */
  172.     SET_COORD(dir, 1.0, 0.0, 0.0);
  173.     lib_output_bounding_slab(&dir);
  174.     SET_COORD(dir, 0.0, 1.0, 0.0);
  175.     lib_output_bounding_slab(&dir);
  176.     SET_COORD(dir, 0.0, 0.0, 1.0);
  177.     lib_output_bounding_slab(&dir);
  178.  
  179.    /* output floor polygon - off white */
  180.    SET_COORD( back_color, 1.0, 0.85, 0.7 ) ;
  181.    txname = lib_output_color(&back_color, 0.1, 0.75, 0.25, 25.0, 0.0, 0.0, 0.0);
  182.    SET_COORD( floor[0], 2.0, 2.0, 0.0 ) ;
  183.    SET_COORD( floor[1], -2.0, 2.0, 0.0 ) ;
  184.    SET_COORD( floor[2], -2.0, -2.0, 0.0 ) ;
  185.    SET_COORD( floor[3], 2.0, -2.0, 0.0 ) ;
  186.    lib_output_polygon(4, floor, txname);
  187.  
  188.    outer_radius=1.0/((double)SIZE_FACTOR-(double)(SIZE_FACTOR-1)*EDGE_RATIO/2.0);
  189.    /* calculate first gear center */
  190.    zero_pt.x = zero_pt.y = -1.0 + outer_radius ;
  191.    zero_pt.z = 1.0 ;
  192.    /* calculate offset */
  193.    offset.x = offset.y = outer_radius * ( 2.0 - EDGE_RATIO ) ;
  194.    offset.z = -1.0 / (double)SIZE_FACTOR ;
  195.  
  196.     /* create gears */
  197.    for ( iz = 0 ; iz < SIZE_FACTOR ; ++iz ) {
  198.       center_pt.z = zero_pt.z + (double)iz * offset.z ;
  199.       for ( iy = 0 ; iy < SIZE_FACTOR ; ++iy ) {
  200.          center_pt.y = zero_pt.y + (double)iy * offset.y ;
  201.          for ( ix = 0 ; ix < SIZE_FACTOR ; ++ix ) {
  202.             center_pt.x = zero_pt.x + (double)ix * offset.x ;
  203.  
  204.             /* output pseudo-random gear color */
  205.             SET_COORD(gear_color,
  206.                       0.01 + FRACTION( (double)(ix*3+iy*2+iz+1)*5.0/7.0 ),
  207.                       0.01 + FRACTION( (double)(iy*3+iz*2+ix+1)*3.0/7.0 ),
  208.                       0.01 + FRACTION( (double)(iz*3+ix*2+iy+1)*2.0/7.0 ));
  209.             color_scale = MAX3( gear_color.x, gear_color.y, gear_color.z );
  210.             gear_color.x /= color_scale ;
  211.             gear_color.y /= color_scale ;
  212.             gear_color.z /= color_scale ;
  213.             if ((ix*4 + iy*2 + iz ) % 5 == 0)
  214.                txname = lib_output_color(&gear_color, 0.1, 0.75, 0.25, 50.0,
  215.                                           0.0, 0.95, 1.1);
  216.             else
  217.                txname = lib_output_color(&gear_color, 0.2, 0.8, 0.0, 0.0,
  218.                                           0.0, 0.0, 0.0);
  219.  
  220.  
  221.             /* output gear */
  222.             angle = PI * (double)( (ix+iy+iz) % 2 ) / (double)(TEETH);
  223.             thickness = MIN( DEPTH_RATIO, 1.0 / ( 2.0 * (double)SIZE_FACTOR));
  224.             create_gear(¢er_pt, angle, outer_radius,
  225.                         (1.0 - EDGE_RATIO) * outer_radius,
  226.                         thickness, txname);
  227.             }
  228.          }
  229.       }
  230. }
  231.